using System;
using System.Collections.Generic;
using System.Text;
using Newtonsoft.Json;
using System.IO;
using it.mintlab.desktopnet.mintar;
using Newtonsoft.Json.Linq;
using it.mintlab.desktopnet.restlib;
using Newtonsoft.Json.Converters;
using Newtonsoft.Json.Serialization;

namespace it.mintlab.desktopnet.health360.server
{
    /// <summary>
    /// Represent a web request
    /// </summary>
    public abstract class WebRequest
    {
        private string operation;

        public string Operation
        {
            get { return operation; }
            set { operation = value; }
        }

        /// <summary>
        /// Generate a request (CRUD or Custom based on contentType and message)
        /// </summary>
        /// <param name="content"></param>
        /// <param name="contentType"></param>
        /// <returns></returns>
        public static WebRequest createFromContent(string content, string contentType)
        {
            switch (contentType)
            {
                case "application/json":
                    JsonReader reader = new JsonTextReader(new StringReader(content));
                    while (reader.Read())
                    {
                        if (reader.TokenType.Equals(JsonToken.PropertyName) && reader.Value.Equals("customRequest"))
                        {
                            reader.Close();

                            // Deserialize settings
                            JsonSerializerSettings settings = new JsonSerializerSettings();
                            settings.ContractResolver = new CamelCasePropertyNamesContractResolver();
                            IsoDateTimeConverter isoDateTimeConverter = new IsoDateTimeConverter();
                            isoDateTimeConverter.DateTimeFormat = "yyyy-MM-ddTHH\\:mm\\:ssZ";
                            settings.Converters.Add(isoDateTimeConverter);
                            settings.Error = delegate(object sender, Newtonsoft.Json.Serialization.ErrorEventArgs args)
                            {
                                //errors.Add(args.ErrorContext.Error.Message);
                                args.ErrorContext.Handled = true;
                            };
    
                            JObject request = JObject.Parse(content);
                            string operation = (string)request["customRequest"]["operation"];
                            Dictionary<string, Object> argDict = new Dictionary<string, object>();
                            JObject arguments = (JObject)request["customRequest"]["params"];
                            foreach (JProperty arg in arguments.Properties())
                            {
                                argDict.Add(arg.Name, ((JValue)arg.Value).Value);
                            }
                            return new CustomWebRequest(operation, argDict);
                        }
                        else if (reader.TokenType.Equals(JsonToken.PropertyName) && reader.Value.Equals("crudRequest"))
                        {
                            reader.Close();

                            // Deserialize settings
                            JsonSerializerSettings settings = new JsonSerializerSettings();
                            settings.ContractResolver = new CamelCasePropertyNamesContractResolver();
                            IsoDateTimeConverter isoDateTimeConverter = new IsoDateTimeConverter();
                            isoDateTimeConverter.DateTimeFormat = "yyyy-MM-ddTHH\\:mm\\:ssZ";
                            settings.Converters.Add(isoDateTimeConverter);
                            settings.Error = delegate(object sender, Newtonsoft.Json.Serialization.ErrorEventArgs args)
                            {
                                //errors.Add(args.ErrorContext.Error.Message);
                                args.ErrorContext.Handled = true;
                            };

                            JObject request = JObject.Parse(content);
                            string operation = (string)request["crudRequest"]["operation"];
                       
                            string modelType = (string)request["crudRequest"]["modelType"];
                            Model model = (Model)JsonConvert.DeserializeObject(request["crudRequest"]["model"].ToString(), Type.GetType(modelType), settings);
                            if (operation.Equals(CRUDWebRequest.OPERATION_SELECT_BY_FILTER))
                            {
                                string sqlFilter = (string)request["crudRequest"]["sqlFilter"];
                                //avoid sql injection
                                int lastChar = sqlFilter.IndexOf(";");
                                if(lastChar != -1)
                                    sqlFilter = sqlFilter.Substring(0, lastChar); 
                                return new CRUDWebRequest(model, operation, sqlFilter);
                            }
                            else
                                return new CRUDWebRequest(model, operation);
                        }
                    }
                    reader.Close();
                    break;
                default:
                    return null;
                    break;
            }
            return null;
        }

        public static string createErrorJSONResponse(string reason)
        {
            StringBuilder sb = new StringBuilder();
            StringWriter sw = new StringWriter(sb);
            using (JsonWriter jsonWriter = new JsonTextWriter(sw))
            {
                jsonWriter.Formatting = Formatting.Indented;
                jsonWriter.WriteStartObject();
                jsonWriter.WritePropertyName("response");
                jsonWriter.WriteStartObject();
                jsonWriter.WritePropertyName("error");
                jsonWriter.WriteStartObject();
                jsonWriter.WritePropertyName("reason");
                jsonWriter.WriteValue(reason);
                jsonWriter.WriteEndObject();
                jsonWriter.WriteEndObject();
                jsonWriter.WriteEndObject();
            }
            return sb.ToString();
        }

    }



    //reader.Read();
    //                        reader.Read();
    //                        if (reader.TokenType.Equals(JsonToken.PropertyName))
    //                        {
    //                            string requestName = reader.Value.ToString();
    //                            Dictionary<string, Object> args = new Dictionary<string, object>();
    //                            string argName;
    //                            Object argValue;
    //                            reader.Read();
    //                            while (reader.Read())
    //                            {
    //                                if (reader.TokenType.Equals(JsonToken.PropertyName))
    //                                {
    //                                    argName = (string)reader.Value;
    //                                    reader.Read();
    //                                    argValue = reader.Value;
    //                                    args.Add(argName, argValue);
    //                                }
    //                                if (reader.TokenType.Equals(JsonToken.EndObject))
    //                                    return new CustomWebRequest(requestName, args, contentType);
    //                            }
    //                        }
}
